//Added code
//struct tm *tmp;
//time_t t;
/*
char opinion[140];


//
	int ptlen;
	int sampleLength = 1000;
	if (argc != 3)
	{
	   fprintf(stderr, "Usage: ./signtest <plain_text_string_size> <sample_size> \n");	
	   exit(1);
	}
	else
	{
		ptlen = atoi(argv[1]);
		sampleLength = atoi(argv[2]);
	}
	
	keysize = 0;

	
	char privkeyprefix[] = "./privkey";
	char keysuffix[] = ".pem";
	char pubkeyprefix[] = "./pubkey";

	
	struct timeval tm;
	gettimeofday(&tm,NULL);
	SEED(tm.tv_sec+tm.tv_usec);
 

*/
//Code added
/*	printf("\nEnter opinion:");
	gets(opinion);  //opinion


	char privkey[100], pubkeyS[100], pubkeyA[100];
	sprintf(privkey, "%s%d%s", privkeyprefix,0, keysuffix);
	sprintf(pubkeyS, "%s%d%s", pubkeyprefix, 0, keysuffix);
	sprintf(pubkeyA, "%s%d%s", pubkeyprefix, 1, keysuffix);

	gettimeofday(&tm, NULL);
	double first = tm.tv_sec + tm.tv_usec/1000000.00;

	char dbuffer[33];

	ltoa(dbuffer, first, 16); 


	char *content[4];

	EVP_PKEY *pubS, *pubA;
	
	pubS = myReadPublicKey(pubkeyS);  
	pubA = myReadPublicKey(pubkeyA);  

	int size_pa,size_ps,size_op,size_db;
	size_ps=sizeof(pubS);
	size_pa=sizeof(pubA);
	size_op=sizeof(opinion);
	size_db=sizeof(dbuffer);

	content = (char *)malloc(size_ps+size_pa+size_op+size_db);
*/
/*
	if(!pubKey)
	{
		EVP_PKEY_free(pubKey);   
		fprintf(stderr,"Error: can't load public key\n");
		exit(1);
	}
*/
/*	FILE *fp;
	char *pubS, *pubA;
	fp=fopen(pubkeyS,"r");
	fgets(pubS,100,fp);
printf("%s",pubS);

	strcpy(content,pubS);
	strcat(content,pubA);
	strcat(content,opinion);
	strcat(content,dbuffer); */
//printf("\n\n %s %s \n\n", opinion, content);

//Encrypting the hash
/*	unsigned char *hash;
	unsigned char *buf;   
	unsigned char *buf2;
	EVP_PKEY *pubKey;
	EVP_PKEY *privKey;
	int len;
	unsigned int *hash_len;
	
	hash_len=sizeof(content)+1;

	ERR_load_crypto_strings();

	privKey = ReadPrivateKey(PRIVFILE);
	if (!privKey) 
	{  
		ERR_print_errors_fp (stderr);    
		exit (1);  
	}

	pubKey = myReadPublicKey(PUBFILE);  
	if(!pubKey)
	{
		EVP_PKEY_free(privKey);   
		fprintf(stderr,"Error: can't load public key\n");
		exit(1);
	}

	buf = malloc(EVP_PKEY_size(privKey));
	buf2 = malloc(EVP_PKEY_size(privKey));

	hash = gen_hash(content, &hash_len); 
	
	len = RSA_private_encrypt(hash_len, hash, buf, privKey->pkey.rsa,RSA_PKCS1_PADDING);
	printf("The length of encrypted hash is %d \n", len); //This is where the thing gets done

	if (len != EVP_PKEY_size(pubKey))
	{
		fprintf(stderr,"Error: ciphertext should match length of key\n");
		exit(1);
	}

	RSA_public_decrypt(len, buf, buf2, pubKey->pkey.rsa,RSA_PKCS1_PADDING);


	if (memcmp(hash, buf2, hash_len) == 0)
	{
		printf("Signature verified \n");
//		printf("%s",content[3]);
	}

	

//	RSA_private_encrypt(hash_len, hash, buf, privKey->pkey.rsa,RSA_PKCS1_PADDING);

*/
	
/*	for (i = 0; i <sampleLength; i++)
	{
		double certTime = 0, verifyTime = 0;
		char privkey[100], pubkey[100];
		sprintf(privkey, "%s%d%s", privkeyprefix, i, keysuffix);
		sprintf(pubkey, "%s%d%s", pubkeyprefix, i, keysuffix);
	        fprintf(stdout,"using privkey: %s\n",privkey);

		unsigned char* cert;

		// get the time here
		gettimeofday(&tm, NULL);
		double first = tm.tv_sec + tm.tv_usec/1000000.00;
		
		int len = 0;
		cert = generate_certificate(str, &len, privkey);
		
		gettimeofday(&tm, NULL);
		double second = tm.tv_sec + tm.tv_usec/1000000.00;
		certTime = second - first;


		gettimeofday(&tm, NULL);
		first = tm.tv_sec + tm.tv_usec/1000000.00;
		//get the time here too
		
		if(verify_certificate(str, cert, len, pubkey) != 1)
		{
			fprintf(stderr, "Verification failure \n");
			exit(1);
		}
		
		gettimeofday(&tm, NULL);
		second = tm.tv_sec + tm.tv_usec/1000000.00;
		verifyTime = second - first;
		
		//free(str); // so unfortunate, this free call causes core dump
		free(cert);
		certavgtime += certTime;
		verifyavgtime += verifyTime;

		//printf("%s %s %d %f %f \n", privkey, pubkey, i, certTime, verifyTime);

	}
	printf("KeySize: %d PlainTextInputSize: %d SampleSize: %d AverageCertificateCreationTime: %f AverageCertificateVerificationTime: %f \n", keysize, ptlen, sampleLength, certavgtime/sampleLength, verifyavgtime/sampleLength);
*/











/*
int main()
{
	char *ct = "This the clear text";
	unsigned char *hash;
	unsigned char *buf;   
	unsigned char *buf2;
	EVP_PKEY *pubKey;
	EVP_PKEY *privKey;
	int len;
	unsigned int hash_len;
	
	hash_len=sizeof(ct)+1;
//	hash=(char *)malloc(sizeof(ct)+1);

	ERR_load_crypto_strings();

	privKey = ReadPrivateKey(PRIVFILE);
	if (!privKey) 
	{  
		ERR_print_errors_fp (stderr);    
		exit (1);  
	}

	pubKey = myReadPublicKey(PUBFILE);  
	if(!pubKey)
	{
		EVP_PKEY_free(privKey);   
		fprintf(stderr,"Error: can't load public key\n");
		exit(1);
	}

	buf = malloc(EVP_PKEY_size(privKey));
	buf2 = malloc(EVP_PKEY_size(privKey));

	hash = gen_hash(ct, &hash_len); 
	
	len = RSA_private_encrypt(hash_len, hash, buf, privKey->pkey.rsa,RSA_PKCS1_PADDING);
	printf("The length of encrypted hash is %d \n", len);

	if (len != EVP_PKEY_size(pubKey))
	{
		fprintf(stderr,"Error: ciphertext should match length of key\n");
		exit(1);
	}

	RSA_public_decrypt(len, buf, buf2, pubKey->pkey.rsa,RSA_PKCS1_PADDING);


	if (memcmp(hash, buf2, hash_len) == 0)
	{
		printf("Signature verified \n");
	}

	EVP_PKEY_free(privKey);
	EVP_PKEY_free(pubKey);
	free(buf);
	free(buf2);
	return 0;
}
*/


/*int gen_hash(char * key, unsigned char * digest)
{
	EVP_MD_CTX mdctx;
	const EVP_MD *md;
	unsigned char *md_value; 
	unsigned int md_len;

	md_value = (unsigned char *)malloc(EVP_MAX_MD_SIZE);

	OpenSSL_add_all_digests();

	md = EVP_get_digestbyname("sha1");

	EVP_MD_CTX_init(&mdctx);
	EVP_DigestInit_ex(&mdctx, md, NULL);
	EVP_DigestUpdate(&mdctx, key, strlen(key));
	EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
	EVP_MD_CTX_cleanup(&mdctx);

	digest = md_value;

	return md_len;
}
*/










/* Hash init */

static const int ITEM_COUNT = 4000;

typedef unsigned int uint32_t;
typedef unsigned short uint16_t;

/*****************************************************************************/
struct key
{
    uint32_t one_ip; uint32_t two_ip; uint16_t one_port; uint16_t two_port;
	
};

struct value
{
    char *id;
};

DEFINE_HASHTABLE_INSERT(insert_some, struct key, struct value);
DEFINE_HASHTABLE_SEARCH(search_some, struct key, struct value);
DEFINE_HASHTABLE_REMOVE(remove_some, struct key, struct value);
DEFINE_HASHTABLE_ITERATOR_SEARCH(search_itr_some, struct key);


/*****************************************************************************/
static unsigned int
hashfromkey(void *ky)
{
    struct key *k = (struct key *)ky;
    return (((k->one_ip << 17) | (k->one_ip >> 15)) ^ k->two_ip) +
            (k->one_port * 17) + (k->two_port * 13 * 29);
}

static int
equalkeys(void *k1, void *k2)
{
    return (0 == memcmp(k1,k2,sizeof(struct key)));
}


    struct key *k, *kk;
    struct value *v, *found;
    struct hashtable *h[20];
//    struct hashtable_itr *itr;
  
    int h_c;

    for(h_c=0;h_c<20;h_c++) {
       h[h_c] = create_hashtable(16, hashfromkey, equalkeys);
       if (NULL == h[h_c]) exit(-1); /*oom*/
    }

//Ends here

